#include "ResourceManager.h"
#include "SceneManager.h"

using namespace GalliumEngine;

ResourceManager::ResourceManager() : Singleton<ResourceManager>()
{
}

ResourceManager::~ResourceManager()
{
}

void ResourceManager::release(std::string sceneName)
{
	for (textures_map_const_itr itr = textures[sceneName].begin(); itr != textures[sceneName].end(); ++itr)
	{
		itr->second->releaseTexture();
	}

	textures[sceneName].clear();

	for (shaders_map_const_itr itr = shaders[sceneName].begin(); itr != shaders[sceneName].end(); ++itr)
	{
		itr->second->deinitialize();
		delete itr->second;
	}

	shaders[sceneName].clear();

	for (fonts_map_const_itr itr = fonts[sceneName].begin(); itr != fonts[sceneName].end(); ++itr)
	{
		itr->second->releaseFont();
		delete itr->second;
	}

	fonts[sceneName].clear();
}

void ResourceManager::releaseAll()
{
	for(std::map<std::string,textures_map>::const_iterator it = textures.begin(); it != textures.end(); ++it)
	{
		for (textures_map_const_itr itr = it->second.begin(); itr != it->second.end(); ++itr)
		{
			itr->second->releaseTexture();
		}
	}

	textures.clear();

	for(std::map<std::string,shaders_map>::const_iterator it = shaders.begin(); it != shaders.end(); ++it)
	{
		for (shaders_map_const_itr itr = it->second.begin(); itr != it->second.end(); ++itr)
		{
			itr->second->deinitialize();
		}
	}

	shaders.clear();

	for(std::map<std::string,fonts_map>::const_iterator it = fonts.begin(); it != fonts.end(); ++it)
	{
		for (fonts_map_const_itr itr = it->second.begin(); itr != it->second.end(); ++itr)
		{
			itr->second->releaseFont();
		}
	}

	fonts.clear();
}

Texture* ResourceManager::loadTexture(std::string file)
{
	std::string sceneName = SceneManager::getInstance()->GetActiveScene()->getId();

	textures_map_itr itr = textures[sceneName].find(file);

	if(itr != textures[sceneName].end())
	{
		return itr->second;
	}
	else
	{
		Texture *texture = new Texture();
		texture->loadTexture(file,true);
		textures[sceneName].insert(textures_pair(file,texture));	

		return texture;
	}
}

Font* ResourceManager::loadFont(std::string file,
	int size)
{
	std::string sceneName = SceneManager::getInstance()->GetActiveScene()->getId();

	fonts_map_itr itr = fonts[sceneName].find(file);

	if(itr != fonts[sceneName].end())
	{
		return itr->second;
	}
	else
	{
		Font* font = new Font();
		font->loadFont(file,size);
	
		fonts[sceneName].insert(fonts_pair(file,font));

		return font;
	}
}

Shader* ResourceManager::loadShader(std::string shaderId,
	std::string vertexShader,
	std::string geometryShader,
	std::string fragmentShader,
	std::vector<BindParams> params)
{
	std::string sceneName = SceneManager::getInstance()->GetActiveScene()->getId();

	shaders_map_itr itr = shaders[sceneName].find(shaderId);

	if(itr != shaders[sceneName].end())
	{
		return itr->second;
	}
	else
	{
		Shader *shader = new Shader(shaderId);
		shader->initialize(vertexShader,geometryShader,fragmentShader,params);
		shaders[sceneName].insert(shaders_pair(shaderId,shader));
		return shader;
	}
}